iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0
Security

密碼學小白的學習之路系列 第 27

[Day 27] 題目(Encoding Challenge) & 凱薩密碼與 rot 13

  • 分享至 

  • xImage
  •  

Encoding Challenge

https://cryptohack.org/challenges/general/

題意:

他說我們已經掌握了各種編碼的竅門,而在這題我們需要學會去自動化這個過程。題目問我們能通過這題的 100 個關卡來獲得 flag 嗎?

伺服器上執行的原始程式碼與註解

13377.py:

#!/usr/bin/env python3

# 匯入必要的模組和函數
from Crypto.Util.number import bytes_to_long, long_to_bytes  
from utils import listener  # Cryptohack 提供的伺服器端模組,不是 Python 的內建模組
import base64  
import codecs  # 用於 Rot13 編碼/解碼
import random  


FLAG = "crypto{????????????????????}"

# 定義編碼方式列表
ENCODINGS = [
    "base64",
    "hex",
    "rot13",
    "bigint",
    "utf-8",
]

# 讀取字典檔中的單詞列表
with open('/usr/share/dict/words') as f:
    WORDS = [line.strip().replace("'", "") for line in f.readlines()]

# 定義 Challenge 類別
class Challenge():
    def __init__(self):
        self.challenge_words = ""  # 用於儲存當前挑戰的單詞
        self.stage = 0  # 用於追踪挑戰的階段

    # 創建挑戰關卡
    def create_level(self):
        self.stage += 1  # 更新階段
        # 隨機選擇 3 個單詞並使用底線(_)連接
        self.challenge_words = "_".join(random.choices(WORDS, k=3))
        # 隨機選擇一種編碼方式
        encoding = random.choice(ENCODINGS)

        # 根據選定的編碼方式對單詞進行編碼
        if encoding == "base64":
            encoded = base64.b64encode(self.challenge_words.encode()).decode()  
        elif encoding == "hex":
            encoded = self.challenge_words.encode().hex() 
        elif encoding == "rot13":
            encoded = codecs.encode(self.challenge_words, 'rot_13')  
        elif encoding == "bigint":
            encoded = hex(bytes_to_long(self.challenge_words.encode())) 
        elif encoding == "utf-8":
            encoded = [ord(b) for b in self.challenge_words]  
        
        # 返回包含編碼類型、編碼結果的字典
        return {"type": encoding, "encoded": encoded}
        

    # 處理使用者輸入的挑戰函數,使用者的輸入必須是 JSON 編碼格式
    def challenge(self, your_input):
        if self.stage == 0:
            return self.create_level()  # 如果是第一階段,建立新挑戰關卡
        elif self.stage == 100:
            self.exit = True  # 如果當前挑戰階段=100 時,設定退出
            return {"flag": FLAG}  # 返回 flag

        # 如果解碼後的結果與原始單詞相符,建立下一個挑戰關卡
        if self.challenge_words == your_input["decoded"]:
            return self.create_level()

        # 如果解碼失敗,返回錯誤信息
        return {"error": "Decoding fail"}


# 將 Challenge 類別注入到內建函數中,讓它能夠在本地運行
import builtins; builtins.Challenge = Challenge  # 參考 Cryptohack FAQ 中的解釋
# 啟動伺服器,監聽端口 13377
listener.start_server(port=13377)

稍微了解一下原始碼的運行可以發現,它會從單字庫隨機選取三個單字,並從五種加密方式隨機選擇一種進行相對應的加密。如果我們返回的解碼結果與原始單詞相符,進入下一個挑戰關卡。當總共進行100次關卡後就會返回flag。

完整程式執行檔

建立一個decode函式,讓它根據輸入的加密類型進行相對應的解密程序。
在還沒有收到flag之前無限次進行接收加密後的訊息並發送解密後的訊息。
當收到flag後,將其print出來。

from pwn import * # pip install pwntools
from Crypto.Util.number import*
import json
import base64
import codecs
r = remote('socket.cryptohack.org', 13377, level = 'debug')

def json_recv():
    line = r.recvline()
    return json.loads(line.decode())

def json_send(hsh):
    request = json.dumps(hsh).encode()
    r.sendline(request)

def decode(type,en):
    if type == "base64":
        decoded= base64.b64decode(en).decode()
    elif type == "hex":
        decoded= bytes.fromhex(en).decode()
    elif type == "rot13":
        decoded = codecs.encode(en, 'rot_13') # rot13的解密與加密相同
    elif type == "bigint":
        decoded = long_to_bytes(int(en, 16)).decode()
    elif type == "utf-8":
        decoded = "".join([chr(b) for b in en])
        
    return decoded
    
flag=True
while(flag):
    received = json_recv()
    if "flag" in received:
        print("#############################")
        print("flag: ")
        print(received["flag"])
        flag=False
        break
    
    to_send = {
        "decoded": decode(received["type"], received["encoded"])
    }
    json_send(to_send)

crypto{3nc0d3_d3c0d3_3nc0d3}

順便介紹一下凱薩密碼與ROT13密碼

凱薩密碼

  • 由古羅馬的尤利烏斯·凱薩所使用的一種加密方式。
  • 加密方式是將每個字母根據一個固定的位移量進行替換。
  • 如果位移量是3,字母"A"會被替換成"D","B"會變成"E"(如下圖所示:)
    https://ithelp.ithome.com.tw/upload/images/20240902/20168165zjSO9gdbaj.png
  • 而這個位移量可以是1到25之間的任何數字,密文會依據位移量而有相對應的變化。

ROT13密碼

* 凱薩密碼的一個特殊變種,只使用固定位移量13。
* 是一個對稱加密系統,因為位移13之後的結果再位移13次就會回到原來的文本。
* 將密文再次加密就會得到明文。
* ROT13 經常用於網路論壇上隱藏敏感或劇透的資訊。
https://ithelp.ithome.com.tw/upload/images/20240902/20168165jOIBAyxXgX.png

參考資料

解題過程:

後話:

昨天沒解完的,解到了今天,在循環接收與發送訊息的那部份卡了很久。明天應該會把AES的下一題解出來,之後就會寫其他平台比較輕鬆的邊複習之前所學邊解題的紀錄。因為腦袋好累...


上一篇
[Day 26] 題目(Network Attacks )
下一篇
[Day 28] 題目(Symmetric-10-1)
系列文
密碼學小白的學習之路31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言